package com.example.demo.controller;


import com.example.demo.common.AjaxResult;
import com.example.demo.common.AppVariable;
import com.example.demo.common.UserSessionUtils;
import com.example.demo.entity.Articleinfo;
import com.example.demo.entity.RegularTime;
import com.example.demo.entity.Upvote;
import com.example.demo.entity.Userinfo;
import com.example.demo.service.ArticleService;
import com.example.demo.service.UpvoteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

@RestController
@RequestMapping("/art")
public class ArticleController {

    @Resource
    private ArticleService articleService;
    @Autowired
    private UpvoteService upvoteService;

    /**
     * 查询用户自己的文章列表.
     */
    @RequestMapping("/mylist")
    public AjaxResult getMyList(HttpServletRequest request) {
        // 获取到当前用户
        Userinfo userinfo = UserSessionUtils.getUser(request);
        // 非空校验
        if (userinfo == null) {
            return AjaxResult.fail(-1, "非法请求");
        }
        // 通过用户 id 查询该用户的文章列表页.
        List<Articleinfo> list = articleService.getMyList(userinfo.getId());
        for (Articleinfo item : list) {
            String content = item.getContent();
            if (content.length() > 100) {
                item.setContent(String.format("%s...",
                        content.substring(0, 100)));
            }
        }
        return AjaxResult.success(list);
    }

    /**
     *  删除用户列表的文章: 只能删除自己的文章.
     *  此处的 id 是文章id, 不是用户id.
     */
    @RequestMapping("/del")
    public AjaxResult delete(Integer id, HttpServletRequest request) {
        if (id == null || id <= 0) {
            // 参数有误.
            return AjaxResult.fail(-1, "参数异常");
        }
        // 拿到当前登录用户.
        Userinfo user = UserSessionUtils.getUser(request);
        if (user == null) {
            return AjaxResult.fail(-1, "用户未登录");
        }
        // 将 点赞表对应的 文章也要删掉(存在的话)
        Upvote upvote = upvoteService.selUpvote(user.getId(), id);
        if (upvote != null) {
            upvoteService.delUpvoteArt(id);
        }
        return AjaxResult.success(articleService.delete(id, user.getId()));
    }

    /**
     *  查询文章详情信息
     */
    @RequestMapping("/detail")
    public AjaxResult getDetail(Integer id, HttpServletRequest request) {
        HashMap<Object, Object> result = new HashMap<>();
        // 非空校验
        if (id == null || id <= 0) {
            return AjaxResult.fail(200, "");
        }
        // 获取文章信息
        Articleinfo articleinfo = articleService.getDetail(id);

        // 获取登录对象, 因为设置了只有登陆的才可以点赞
        Userinfo userinfo = UserSessionUtils.getUser(request);
        if (userinfo == null) {
            // 默认就是没有点赞
            result.put("art", articleinfo);
            result.put("state", 0);
            return AjaxResult.success(result);
        }
        // 获取文章的点赞标志
        Upvote upvote = upvoteService.selUpvote(userinfo.getId(), id);
        int state = 0;
        if (upvote != null) {
            state = upvote.getState();
        }
        // 返回数据
        result.put("art", articleinfo);
        result.put("state", state);
        return AjaxResult.success(result);
    }

    /**
     *  实现文章阅读量+1
     */
    @RequestMapping("/updrcount")
    public AjaxResult updRCount(Integer id) {
        if (id == null || id <= 0) {
            return AjaxResult.fail(-1, "未知错误");
        }
        // 设置数据库的阅读量 +1
        return AjaxResult.success(articleService.updRCount(id));
    }


    /**
     *  添加文章
     */
    @RequestMapping("/add")
    public AjaxResult add(Articleinfo articleinfo, HttpServletRequest request) {
        // 1. 非空校验
        if (articleinfo == null || !StringUtils.hasLength(articleinfo.getTitle())
                ||!StringUtils.hasLength(articleinfo.getContent())) {
            return AjaxResult.fail(-1, "非法参数");
        }
        // 2. 数据库添加操作.
        // 2.1 先得到当前登录用户的uid, 设置发布的文章的归属人.
        Userinfo userinfo = UserSessionUtils.getUser(request);
        if (userinfo == null || userinfo.getId() <= 0) {
            // 无效的登录用户
            return AjaxResult.fail(-2, "无效的登录用户");
        }
        articleinfo.setUid(userinfo.getId());
        // 2.2 添加数据库并将文章信息返回给前端.
        return AjaxResult.success(articleService.add(articleinfo));
    }


    /**
     *  修改文章
     */
    @RequestMapping("/update")
    public AjaxResult update(Articleinfo articleinfo, HttpServletRequest request) {
        // 参数校验
        if (articleinfo == null || !StringUtils.hasLength(articleinfo.getTitle())
                || articleinfo.getId() == null || !StringUtils.hasLength(articleinfo.getContent())) {
            // 非法参数
            return AjaxResult.fail(-1, "非法参数");
        }
        // 得到当前登录用户 id
        Userinfo userinfo = UserSessionUtils.getUser(request);
        if (userinfo == null || userinfo.getId() <= 0) {
            // 无效用户
            return AjaxResult.fail(-2, "无效用户");
        }
        // 很核心的代码!!解决了文章归属人判定的问题. 用户 id 不能让前端传!!
        articleinfo.setUid(userinfo.getId());

        // 设置修改时间
        articleinfo.setUpdatetime(LocalDateTime.now());

        return AjaxResult.success(articleService.update(articleinfo));
    }

    /**
     * 查询文章公共列表页(分页)
     *
     * @param pindex 当前页码(从1开始).
     * @param psize 每页显示的最大条数.
     * @return 文章列表
     */
    @RequestMapping("/listbypage")
    public AjaxResult getListByPage(Integer pindex, Integer psize) {
        // 1. 校验参数
        if (pindex == null || pindex <= 1) {
            pindex = 1;
        }
        if (psize == null || psize < 1) {
            psize = 20;
        }

        // a. 查询总共有多少条数据
        int totalCount = articleService.getTotalCount();
        // 计算当前列表最大页数.
        // b. 最大页数 = 总数 / psize --> 使用进一法.
        double maxPage = 1.0 * totalCount / psize;
        int pcount = (int)Math.ceil(maxPage);


        // 2. 分页公式: 升序: (当前页码 - 1) * 每页显示最大条数.  / 降序: 总数 - (psize * 当前页码)
         int offsize = (pindex - 1) * psize;
        System.out.println("off: " + offsize);
        // 文章列表数据
        List<Articleinfo> list = articleService.getListByPage(psize, offsize);
        for (Articleinfo item : list) {
            String content = item.getContent();
            if (content.length() > 100) {
                item.setContent(String.format("%s......",
                        content.substring(0, 100)));
            }
        }


        HashMap<String, Object> result = new HashMap<>();
        result.put("list", list);
        result.put("pcount", pcount);

        return AjaxResult.success(result);
    }

    /**
     *  发布草稿
     */
    @RequestMapping("/add2")
    public AjaxResult addDraftList(Articleinfo articleinfo, HttpServletRequest request) {
        // 1. 参数校验
        if (articleinfo == null || !StringUtils.hasLength(articleinfo.getTitle())
            || !StringUtils.hasLength(articleinfo.getContent()) || articleinfo.getState() != -1) {
            return AjaxResult.fail(-1, "非法参数");
        }
        // 拿到登录用户
        Userinfo userinfo = UserSessionUtils.getUser(request);
        if (userinfo == null) {
            return AjaxResult.fail(-2, "无效用户!");
        }
        // 设置文章草稿归属人
        articleinfo.setUid(userinfo.getId());
        // 添加数据库
        return AjaxResult.success(articleService.addDraftList(articleinfo));
    }

    /**
     *  修改草稿
     */
    @RequestMapping("/updatedraft")
    public AjaxResult updateDraft(Articleinfo articleinfo, HttpServletRequest request) {
        // 参数校验
        if (articleinfo == null || articleinfo.getId() == null ||
                !StringUtils.hasLength(articleinfo.getTitle()) || !StringUtils.hasLength(articleinfo.getContent())) {
            // 非法参数
            return AjaxResult.fail(-1, "非法参数");
        }
        // 得到当前登录用户 id
        Userinfo userinfo = UserSessionUtils.getUser(request);
        if (userinfo == null || userinfo.getId() <= 0) {
            // 无效用户
            return AjaxResult.fail(-2, "无效用户");
        }
        // 很核心的代码!!解决了文章归属人判定的问题. 用户 id 不能让前端传!!
        articleinfo.setUid(userinfo.getId());

        // 设置修改时间
        articleinfo.setUpdatetime(LocalDateTime.now());

        return AjaxResult.success(articleService.updateDraft(articleinfo));
    }

    /**
     *  查询草稿箱的文章列表
     */
    @RequestMapping("/mydraftlist")
    public AjaxResult getDraftList(HttpServletRequest request) {
        // 拿到当前登录的用户
        Userinfo userinfo = UserSessionUtils.getUser(request);
        if (userinfo == null) {
            return AjaxResult.fail(-1, "非法用户");
        }
        // 查询数据库
        List<Articleinfo> list = articleService.getDraftList(userinfo.getId(), -1);
        for (Articleinfo item : list) {
            String content = item.getContent();
            if (content.length() > 100) {
                item.setContent(String.format("%s...", content.substring(0, 100)));
            }
        }
        return AjaxResult.success(list);
    }

    /**
     *  更新点赞数
     */
    @RequestMapping("/prize")
    public AjaxResult updPrizeCount(Articleinfo articleinfo, HttpServletRequest request) {
        // 非空校验
        if (articleinfo == null || articleinfo.getId() <= 0) {
            return AjaxResult.fail(-1, "非法参数");
        }

        // 登陆了才可以点赞
        Userinfo userinfo = UserSessionUtils.getUser(request);
        if (userinfo == null) {
            return AjaxResult.fail(-2, "非法操作");
        }
        // 点赞后将 点赞表的 state 设为 1
        Upvote upvote = upvoteService.selUpvote(userinfo.getId(), articleinfo.getId());
        if (upvote == null) {
            // 第一次点赞文章, 插入
            upvoteService.insertUpvote(userinfo.getId(), articleinfo.getId(), 1);
            // 增加点赞量
            articleService.updPrizeCount(articleinfo.getId());
        } else {
            // 不是第一次
            if (upvote.getState() == 1) {
                // 减少
                articleService.incPrizeCount(articleinfo.getId());
                upvote.setState(0);
                upvoteService.updUpvote(upvote);
            } else {
                // 增加
                articleService.updPrizeCount(articleinfo.getId());
                upvote.setState(1);
                upvoteService.updUpvote(upvote);
            }
        }
        // 设置点赞数目后返回数据
        articleinfo.setPrize(articleService.getPrizeCount(articleinfo.getId()));

        HashMap<Object, Object> result = new HashMap<>();
        result.put("state", upvote == null ? 1 : upvote.getState());
        result.put("prize", articleinfo.getPrize());

        return  AjaxResult.success(result);
    }

    /**
     *  定时发布
     */
    @RequestMapping("/time")
    public AjaxResult timePush(Articleinfo articleinfo ,RegularTime regularTime,
                               HttpServletRequest request) throws ParseException, InterruptedException {
        // 判空
        if (regularTime == null || !StringUtils.hasLength(regularTime.getYear()) || !StringUtils.hasLength(regularTime.getMonth())
                    || !StringUtils.hasLength(regularTime.getDay()) || !StringUtils.hasLength(regularTime.getHour())
                    || !StringUtils.hasLength(regularTime.getMinute()) || !StringUtils.hasLength(articleinfo.getContent())
                    || !StringUtils.hasLength(articleinfo.getTitle()))  {
            return AjaxResult.fail(-1, "非法参数");
        }

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");

        String inputTime = regularTime.getYear() + "-" + regularTime.getMonth() + "-"
                + regularTime.getDay() + " " + regularTime.getHour() + ":"
                + regularTime.getMinute();
        // 拿到用户设定的时间
        Date time = dateFormat.parse(inputTime);
        // 判断用户输入时间是否合理 是否存在
        String timeStr = dateFormat.format(time);
        if (!timeStr.equals(inputTime)) {
            // 输入的时间不正确
            return AjaxResult.fail(-9, "参数错误");
        }

        // 判断是不是设置了过去时间
        // 获取当前时间
        Date localTime = new Date();
        if (time.getTime() - localTime.getTime() < 0) {
            // 设置了过去时间, 时光机只能穿越到未来~
            return AjaxResult.fail(-2, "参数错误!");
        }

        // 只能穿越到未来的10天.
        if (time.getTime() - localTime.getTime() > AppVariable.REGULAR_TIME) {
            // 时光机只能穿越到未来10天~
            return AjaxResult.fail(-2, "参数错误!");
        }

        //
        Userinfo userinfo = UserSessionUtils.getUser(request);
        if (userinfo == null || userinfo.getId() <= 0) {
            // 无效的登录用户
            return AjaxResult.fail(-3, "无效的登录用户");
        }
        articleinfo.setUid(userinfo.getId());

        // 使用定时器实现定时发布.
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                AjaxResult.success(articleService.add(articleinfo));
            }
        }, time.getTime() - localTime.getTime());

//        // 创建一个线程实现定时发布
//        Thread thread = new Thread(() -> {
//            while (true) {
//                Date localTime2 = new Date();
//                if (time.getTime() - localTime2.getTime() <= 0) {
//                   AjaxResult.success(articleService.add(articleinfo));
//                   return;
//                }
//                // 1s 判断一次
//                try {
//                    Thread.sleep(1000);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }
//        });
//        thread.start();

        return AjaxResult.success(1);
    }

    /**
     *  查询个人点赞收藏的文章
     */
    @RequestMapping("/collect")
    public AjaxResult myCollectArt(HttpServletRequest request) {
        // 拿到当前登录用户
        Userinfo userinfo = UserSessionUtils.getUser(request);
        if (userinfo == null) {
            // 未登录 非法的操作
            return AjaxResult.fail(-1,"非法操作");
        }
        // 查询
        List<Articleinfo> result = articleService.getUpvoteArtList(userinfo.getId());
        for (Articleinfo item : result) {
            String content = item.getContent();
            if (content.length() > 100) {
                item.setContent(String.format("%s...", content.substring(0, 100)));
            }
        }
        return AjaxResult.success(result);
    }

    /**
     *  根据搜索内容查询文章
     */
    @RequestMapping("/search")
    public AjaxResult searchList(String search) {
        if (search == null ) {
            return AjaxResult.fail(-1, "非法请求");
        }


        // search 可能是用户名, 也可能是标题, 所以要查两次.
        // 1. 文章标题
        List<Articleinfo> result = articleService.searchListByTitle(search);
        // 2. 文章作者
        List<Articleinfo> list = articleService.searchListByNickName(search);
        result.addAll(list);

        // 用于去重
        HashSet<Articleinfo> set = new HashSet<>(result);

        for (Articleinfo item : result) {
            String content = item.getContent();
            if (content.length() > 100) {
                item.setContent(String.format("%s...", content.substring(0, 100)));
            }
        }

        return AjaxResult.success(set);
    }

}
